home *** CD-ROM | disk | FTP | other *** search
/ The 640 MEG Shareware Studio 4 / The 640 Meg Shareware Studio CD-ROM Volume IV (Data Express)(1994).ISO / clang / cenvid.zip / PATHSUBS.BAT < prev    next >
DOS Batch File  |  1993-06-25  |  9KB  |  232 lines

  1. @echo off
  2. REM PathSubs.bat - Compact the PATH statement by using SUBST for the paths in
  3. REM                the list.  Also allow to add or delete a path.  See the
  4. REM                Instructions() function for a description of how to use
  5.  
  6. subst | cenvi %0.bat %1 %2 %3 %4 %5 %6 %7 %8 %9
  7. GOTO CENVI_EXIT
  8.  
  9. Instructions()
  10. {
  11.    printf("\a\n")
  12.    printf("PathSubs - Keep the PATH environment variable as short as possible buy using\n")
  13.    printf("           DOS's SUBST command to replace PATH directories with drive letters.\n")
  14.    printf("\n")
  15.    printf("SYNTAX:  PathSubs [ < + | - > d:\\path ]\n")
  16.    printf("\n")
  17.    printf("Where:  +        Add a path to the PATH variable, if not already there.\n")
  18.    printf("        -        Remove a path from the PATH variable, if it is there.\n")
  19.    printf("        d:\\path  The FULL directory to add or remove from PATH.\n")
  20.    printf("\n")
  21.    printf("The following table shows examples of the SUBST command.\n");
  22.    printf("\n")
  23.    printf("PathSubs            Compacts the current path using drive substitutions\n")
  24.    printf("PathSubs + D:\\UTL   Add D:\UTL to the current PATH\n")
  25.    printf("PathSubs - D:\\UTL   Remove D:\UTL from the current PATH\n")
  26.    printf("\n")
  27. }
  28.  
  29. // The following code uses the path structure which has the elements:
  30. //   Count      : number of directories in the path
  31. //   path[Count].Dir   : array of Count strings, each containing a full directory
  32. //   path[Count].Drive : drive letter substituted here, else 0 for not subst
  33. // and also the Subs structure which has the elements
  34. //   Count        : number of drives Substituted
  35. //   sub[Count].Drive : array of Count drive letters substituted for Dir
  36. //   sub[Count].Dir   : array of Count strings for the path of each substituted driev
  37.  
  38. main(ArgCount,ArgStrings)
  39. {
  40.    // Decide what to do from input
  41.    if ( ArgCount == 3 ) {
  42.       Command = ArgStrings[1]
  43.       CommandPath = ArgStrings[2]
  44.       if ( Command[1] != 0  || ( Command[0] != '+'  &&  Command[0] != '-' ) ) {
  45.          // Invalid input, so just show how to use and quit
  46.          Instructions()
  47.          return(1)
  48.       }
  49.    } else if ( ArgCount != 1 ) {
  50.       // Invalid input, so just show how to use and quit
  51.       Instructions()
  52.       return(1)
  53.    }
  54.    // Build lists of substituted drives and of paths
  55.    Subs = BuildSubsArray()
  56.    Paths = SeparatePATHIntoDirs(Subs)
  57.    // implement new command based on input arguments
  58.    if ( ArgCount == 3 ) {
  59.       if ( Command[0] == '+' )
  60.          AddPath(CommandPath,Paths)
  61.       else
  62.          RemovePath(CommandPath,Paths,Subs)
  63.    }
  64.    CompactPaths(Paths,Subs)
  65.    ShowCurrentPath(Paths)
  66.    return(0)
  67. }
  68.  
  69. ShowCurrentPath(p)
  70. {
  71.    printf("PATH=")
  72.    for ( i = 0, count = 0; i < p.Count; i++ ) {
  73.       if ( p.path[i].Dir != NULL ) {
  74.          if ( count++ ) printf(";")
  75.          printf("%s",p.path[i].Dir)
  76.       }
  77.    }
  78.    printf("\n")
  79. }
  80.  
  81. AddPath(Dir,p)
  82. {
  83.    // First check if this directory is already in the path
  84.    for ( i = 0; i < p.Count; i++ ) {
  85.       if ( 0 == stricmp(Dir,p.path[i].Dir) ) {
  86.          printf("Directory \"%s\" is already in the PATH\n",p.path[i].Dir)
  87.          return
  88.       }
  89.    }
  90.    // was not found above in the path, and so add to end of path list
  91.    strcpy(p.path[p.Count].Dir,Dir)
  92.    p.path[p.Count].Drive = 0  // assume it is not substituted
  93.    p.Count++
  94. }
  95.  
  96. RemovePath(Dir,p,s)
  97. {
  98.    // First check that this directory is already in the path
  99.    for ( i = 0; i < p.Count; i++ ) {
  100.       if ( 0 == stricmp(Dir,p.path[i].Dir) ) {
  101.          break
  102.       }
  103.    }
  104.    if ( i == p.Count )
  105.       printf("Directory \"%s\" is not in the PATH\n",Dir)
  106.    else {
  107.       // remove this directory from the path, and remove its SUBST
  108.       if ( (drive = toupper(p.path[i].Drive)) != 0 ) {
  109.          // this path has a SUBSTITUTED drive, and so remove that subst drive
  110.          for ( j = 0; j < s.Count; j++ ) {
  111.             if ( s.sub[j].Drive == drive )
  112.                break;
  113.          }
  114.          s.sub[j].Drive = 0;
  115.          // use DOS's SUBST utility to un-substitute this drive
  116.          system("SUBST %c: /D",drive)
  117.       }
  118.       // set path structure to know this path is no longer there
  119.       p.path[i].Drive = 0;
  120.       p.path[i].Dir = NULL
  121.    }
  122. }
  123.  
  124. BuildSubsArray()  // Subst output was piped to this program, and so use that output
  125.                   // to build list of substituted drives and paths they point to.
  126.                   // output line is of the form "G: is substituted for C:\OS2"
  127. {
  128.    for ( s.Count = 0; NULL != (line=gets()); s.Count++ ) {
  129.       // first letter of SUBST is the drive letter
  130.       s.sub[s.Count].Drive = toupper(line[0]);
  131.       // last string before whitespace is the path
  132.       for ( d = line + strlen(line); d[-1] != ' '; d-- ) ;
  133.       strcpy(s.sub[s.Count].Dir,d)
  134.    }
  135.    return(s)
  136. }
  137.  
  138.  
  139. SeparatePATHIntoDirs(subs) // Separate the PATH environment variable into
  140.                            // individual paths, return element Count to how many
  141.                            // paths, and setting each Dir[] element to a path.
  142.                            // any paths that fit into the subst array will be
  143.                            // replaced by their full subst path
  144. {
  145.    Paths.Count = 0
  146.    p = PATH
  147.    while ( NULL != p  &&  0 != p[0] ) {
  148.       if ( ';' == p[0] )
  149.          p++   // skip semi-colons
  150.       else {
  151.          strcpy(NewDir,p)
  152.          if ( NULL != (c = strchr(NewDir,';')) )
  153.             c[0] = 0;
  154.          // check if this is a "A:\" type path and if it is substituted
  155.          Paths.path[Paths.Count].Drive = 0   // assume it is not substituted
  156.          if ( 0 == strcmp(NewDir+1,":\\") ) {
  157.             // loop through subst to see if this is one of those
  158.             for ( i = 0; i < subs.Count; i++ ) {
  159.                if ( toupper(NewDir[0]) == subs.sub[i].Drive ) {
  160.                   // put in the real path for this substituted one
  161.                   NewDir = subs.sub[i].Dir
  162.                   Paths.path[Paths.Count].Drive = subs.sub[i].Drive
  163.                   break
  164.                }
  165.             }
  166.          }
  167.          strcpy(Paths.path[Paths.Count++].Dir,NewDir)
  168.          p = strchr(p,';')
  169.       }
  170.    }
  171.    return(Paths)
  172. }
  173.  
  174. CompactPaths(p,s) // this writes the PATH statement in compacted form, substituting
  175.                   // all drives for a path whenever it can.  It assumes that it will
  176.                   // Subst on any drive letter that isn't used already.
  177. {
  178.    TempPath[0] = '\0'  // restart directories from scratch
  179.    SubstDir = "A:\\" // template for what a subdir looks like
  180.    for ( i = 0; i < p.Count; i++ ) {
  181.       if ( p.path[i].Dir != NULL ) {
  182.          if ( p.path[i].Drive != 0 ) {
  183.             // this path already has a drive letter substituted, and so keep it
  184.             SubstDir[0] = p.path[i].Drive
  185.             strcat(TempPath,SubstDir)
  186.          } else if ( strlen(p.path[i].dir) <= 3 ) {
  187.             // path can't get any shorter by substituting, and so keep it as it is
  188.                strcat(TempPath,p.path[i].Dir)
  189.          } else {
  190.             // get the next drive letter for substituting
  191.             drive = NextFreeDrive()
  192.             if ( drive != 0 ) {
  193.                // create a new SUBST drive for this path
  194.                system("SUBST %c: %s",drive,p.path[i].Dir)
  195.                SubstDir[0] = p.path[i].Drive = drive
  196.                strcat(TempPath,SubstDir)
  197.                // add this new drive to list of substituted drives
  198.                strcpy(s.sub[s.Count].Dir,p.path[i].Dir)
  199.                s.sub[s.Count].Drive = drive
  200.                s.Count++
  201.             } else {
  202.                // there are no more available free drives, and so simply add this dir
  203.                strcat(TempPath,p.path[i].Dir)
  204.             }
  205.          }
  206.          strcat(TempPath,";")
  207.       }
  208.    }
  209.    // remove the final semi-colon
  210.    TempPath[strlen(TempPath)-1] = 0
  211.    PATH=TempPath
  212. }
  213.  
  214. NextSubstDrive = 'D'    // this global is incremented for each drive to test
  215.  
  216. NextFreeDrive() // return a character for the next available free drive letter
  217.                 // or '\0' if no drive available. Check if a drive is available
  218.                 // by seeing if there's a current path for that drive
  219. {
  220.    CurDir = "C:."  // this string, with drive letter substituted tested for curdir
  221.    while ( NextSubstDrive <= 'Z' ) {
  222.       CurDir[0] = NextSubstDrive++
  223.       if ( NULL == FullPath(CurDir) ) {
  224.          return( NextSubstDrive - 1 )
  225.       }
  226.    }
  227.    // no free drive was found; indicate by returning 0
  228.    return '\0'
  229. }
  230.  
  231. :CENVI_EXIT
  232.